home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gdb / gdb_18s.zoo / atarist.c next >
C/C++ Source or Header  |  1992-04-27  |  19KB  |  744 lines

  1.  
  2. /* glue funs and things that substitute for eunuchs funs */
  3.  
  4. #include <stdio.h>
  5. #include <osbind.h>
  6. #include <setjmp.h>
  7. #include <ctype.h>
  8. #include <signal.h>
  9. #include <regexp.h>
  10. #include "st-traps.h"
  11. #include "wait.h"
  12. #include "m-atari.h"
  13. #include "defs.h"
  14. #include "symtab.h"
  15.  
  16. struct tpa            /* what the hell does 'tpa' stand for anyway?*/
  17. {
  18.     struct tpa * self;    /* self or parent??? */
  19.     long * memtop;        /* top of mem this tpa */
  20.     long * text_base;
  21.     long text_size;
  22.     long * data_base;
  23.     long data_size;
  24.     long * bss_base;
  25.     long bss_size;
  26.     /* there's more crap here, but I think it doesn't matter */
  27. };
  28.  
  29. struct tpa * child_tpa;
  30. int atari_debug = 0;
  31.  
  32. #if 0
  33. long _stksize = 128 *1024L;    /* might as well put this here */
  34. #else
  35. long _initial_stack = 512 *1024L;
  36. #endif
  37.  
  38. #define    CHILD_PID_KLUDGE    1
  39.  
  40. int child_is_running = 0;
  41.  
  42. long old_vectors[10];
  43. long old_trap_0_vector;
  44. long old_trap_f_vector;
  45.  
  46. long set_exception_vector();
  47.  
  48. #if 1 /* def JRDLIB */
  49. /* for st-infru.c */
  50. char * sys_siglist[] = 
  51. {
  52.     "null",
  53.     "alarm",
  54.     "bus error",
  55.     "address error",
  56.     "illegal instruction",
  57.     "div by zero",
  58.     "CHK instruction",
  59.     "TRAPV instruction",
  60.     "priv violation",
  61.     "T-bit trap",
  62.     "Breakpoint",
  63.     "interrupt",
  64.     "quit"
  65. };
  66. #endif
  67.  
  68. /* for st-inflo.c... */
  69. static volatile jmp_buf exec_context, pre_pexec_context;
  70.  
  71. static char  kludge_cmd[MAXPATHLEN];
  72. static char * kludge_argstring;
  73. static char * kludge_env;
  74. static volatile long kludge_pexec_result;
  75.  
  76. static char pexec_stack[256];
  77.  
  78. st_execle_kludge(args, env)
  79. /* BOGON ALERT!!! the caller has 'args' declared as a char **, but
  80.    that's clearly bogus, given the way it's constructed.  Look in
  81.    infcmd.c.  It's really a char *.  I hate C...  */
  82. char * args;
  83. char ** env;
  84. {
  85.     int i, envlen;
  86.     char cmdname[80], argstring[258];
  87.     char * p, * q;
  88.     static char run_already = 0;
  89.  
  90.     if(run_already)
  91.     return -9999;
  92.     else
  93.     run_already = 1;
  94.     
  95.     /* zzz */
  96.     /*
  97.       fprintf_filtered(stderr, "Execle_kludge:\n");
  98.       fprintf_filtered(stderr, "\t'%s'\n", args);
  99.       
  100.       fprintf_filtered(stderr, "\tenv:\n");
  101.       for (i = 0 ; env[i] ; i++)
  102.       fprintf_filtered(stderr, "\t\t'%s'\n", env[i]);
  103.       */
  104.     
  105.     /* construct the environment string */
  106.     envlen = 0;
  107.     for (i = 0; env[i]; i++)
  108.     envlen += strlen(env[i]) + 1;
  109.     envlen += 1;
  110.     
  111.     p = kludge_env = xmalloc(envlen);
  112.     
  113.     for (i = 0; env[i]; i++)
  114.       {
  115.     /*
  116.      * NOTE: in main.c, we converted the PATH environment variable into
  117.      * POSIX form. Here, we convert back into gulam form. Note that the
  118.      * new variable will be shorter than the old, so space is not a
  119.      * problem.
  120.      */
  121.     if (!strncmp (env[i], "PATH=", 5))
  122.       {
  123.         strncpy (p, env[i], 5);
  124.         p += 5;
  125.         for (q = env[i] + 5; *q; q++)
  126.           {
  127.         if (!strncmp (q, "/dev/", 5) && q[5])
  128.           {
  129.             *p++ = q[5];
  130.             *p++ = ':';
  131.             q += 5;
  132.           }
  133.         else if (*q == ':')
  134.           *p++ = ',';
  135.         else if (*q == '/')
  136.           *p++ = '\\';
  137.         else
  138.           *p++ = *q;
  139.           }
  140.       }
  141.     else
  142.       for (q = env[i]; *q; q++)
  143.         *p++ = *q;
  144.     *p++ = '\0';
  145.       }
  146.     *p = '\0';
  147.     
  148.     /* the obligatory cmd line parsing */
  149.     cmdname[0] = '\0';
  150.     /* cmd string has 'exec' in front of it. */
  151.     for (p = args + 4 ; (*p && isspace(*p)) ; p++)
  152.     ;
  153.     for (q = &cmdname[0] ; (*p && !isspace(*p)) ; )
  154.       *q++ = *p++;
  155.     *q = '\0';
  156.     for ( ; (*p && isspace(*p)) ; p++)
  157.     ;
  158.     argstring[1] = '\0';
  159.     for (q = &argstring[1] ; (*p) ; )
  160.     *q++ = *p++;
  161.     *q = '\0';
  162.     argstring[0] = strlen(&argstring[1]);
  163.     unx2dos(&cmdname[0], kludge_cmd);
  164.     
  165.     exception_number = 0;
  166.     old_ipl_2_vector = 
  167.     set_exception_vector(26, ipl_2_vector);    /* our startup trap */
  168.     if (!setjmp(exec_context))
  169.     {
  170.     /* ok, we're either coming thru here the first time, before
  171.        the spawn, or after taking the kludge return.  child_running
  172.        tells us which one */
  173.     if (child_is_running)
  174.     {
  175.         /* something's really fucked here.  We're not supposed to
  176.            be able to come thru here except when we're starting
  177.            things */
  178.         fprintf_filtered(stderr, "Internal error!!! child already running?\n");
  179.         return(0);
  180.     }
  181.     else
  182.     {
  183.         /* set the running flag, arrange to return to that setjmp above,
  184.            and start the child. */
  185.         child_is_running = 1;
  186.         setup_fake_debugger_context(exec_context);
  187.         
  188.         /* if we could be sure of the stack, we'd say...
  189.            Pexec(PE_LOADGO, cmdname, argstring, env);
  190.            but we can't.  instead... */
  191.         
  192.         /*        fprintf_filtered(stderr, "Pexec('%s', '%s')\n",
  193.             &cmdname[0], &argstring[1]);
  194.             */
  195.         /*        kludge_cmd = &cmdname[0]; */
  196.         kludge_argstring = &argstring[0];
  197.         
  198.         if(setjmp(pre_pexec_context))
  199.         {
  200.         free(kludge_env);
  201.         /* we're returning after the child exits.  the stack
  202.            is all fucked here, so reset to top level */
  203.         child_is_running = 0;
  204.         fprintf(stderr, "Program exitted with status %ld\n", 
  205.             kludge_pexec_result);
  206.         exception_number = SIGTRACE;    /* not really... */
  207.         inferior_died();        /* I think this is safe here */
  208.         return_to_top_level();    /* clean up stack and restart */
  209.         return(CHILD_PID_KLUDGE);   /* just in case ... */
  210.         
  211.         }
  212.         /* must make sp point to someplace nonvolatile, as we're going to do 
  213.            a bunch of context switching before we actually 'exit' from this
  214.            pexec. */
  215. #ifndef OLDTOS
  216.  /* default - TOS 1.4 or better required
  217.     use Pexec 3+6 */
  218.  
  219.         asm volatile("\
  220.          movel #_pexec_stack+252,sp
  221.         movel _kludge_env,sp@-
  222.         movel _kludge_argstring,sp@-
  223.         movel #_kludge_cmd,sp@-
  224.         movew #3,sp@-
  225.         movew #0x4B,sp@-
  226.         trap #1
  227.          addw  #16,sp
  228.          clrl  sp@-
  229.          movel d0, sp@-
  230.             clrl  sp@-
  231.          movew #6, sp@-
  232.             movew #0x4B,sp@-
  233.          trap #1
  234.         movel d0,_kludge_pexec_result");
  235. #else
  236. /* pre tos 1.4 -- get a life man 
  237.    use Pexec 0 */        
  238.         asm volatile("\
  239.          movel #_pexec_stack+252,sp
  240.         movel _kludge_env,sp@-
  241.         movel _kludge_argstring,sp@-
  242.         movel #_kludge_cmd,sp@-
  243.         movew #0,sp@-
  244.         movew #0x4B,sp@-
  245.         trap #1
  246.         movel d0,_kludge_pexec_result");
  247. #endif
  248.         
  249. #if 0
  250.         free(kludge_env);
  251.         /* we're returning after the child exits.  the stack
  252.            is all fucked here, so reset to top level */
  253.         child_is_running = 0;
  254.         exception_number = SIGTRACE;    /* not really... */
  255.         inferior_died();        /* I think this is safe here */
  256.         return_to_top_level();        /* clean up stack and restart */
  257. #else
  258.         longjmp(pre_pexec_context, 1);
  259. #endif
  260.     }
  261.     }
  262.     else
  263.     {
  264.     /* we have just spawned the child, and are returning from
  265.        preparing to execute him.  return
  266.        the fake pid so we can continue initialiation */
  267.     set_exception_vector(26, old_ipl_2_vector);
  268.         {
  269.         long * child_sp = (long *)child_context.registers[15];
  270.         child_tpa = (struct tpa * )child_sp[1];
  271.         /*      fprintf_filtered(stderr, "child tpa at %X\n", child_tpa); */
  272.         relocate_apropriate_symbols(child_tpa->text_base);
  273.         exception_number = 0;
  274.         }
  275.     }
  276.     return(CHILD_PID_KLUDGE);
  277. }
  278.  
  279. #if 1 /* def JRDLIB */
  280. /* called various places */
  281. int kill(fake_pid, signal)
  282. int fake_pid;
  283. int signal;
  284. {
  285.   extern void request_quit();
  286.  
  287.     if (fake_pid == CHILD_PID_KLUDGE)
  288.     {
  289.     /* if the child is running, then TOS thinks we're it, so just exit */
  290.     if (child_is_running)
  291.         Pterm0();
  292.     /* doesn't return... */
  293.     else
  294.         fprintf_filtered(stderr, "Internal error: attempt to kill when child not running\n");
  295.     }
  296.     else if (fake_pid == getpid ())
  297.       {
  298.     if (signal == SIGINT)
  299.       request_quit();
  300.       }
  301.     else
  302.     fprintf_filtered(stderr, "You can't kill pid %d, bozo!\n", fake_pid);
  303.     
  304.     return(-1);
  305. }
  306. #endif
  307.  
  308. /* called from various places, mostly st-infru.c */
  309. int st_wait_kludge(w)
  310. WAITTYPE * w;
  311. {
  312.     /*  fprintf_filtered(stderr, "st-wait-kludge: running %d exc %d\n",
  313.       child_is_running, exception_number);    */
  314.     if (child_is_running)
  315.     {
  316.     WSETSTOP(*w, exception_number);
  317.     return(CHILD_PID_KLUDGE);
  318.     }
  319.     else
  320.     {
  321.     WSETEXIT(*w, 0);
  322.     return(-1);
  323.     }
  324. }
  325.  
  326.  
  327. static char *regcomp_error = 0;
  328. static regexp *compiled_regex = 0;
  329.  
  330. /* Remember the last error message from regcomp */
  331. void regerror(message)
  332. char *message;
  333. {
  334.     regcomp_error = message;
  335. }
  336.  
  337. char *re_c